#include "Connection.h"
#include "EventLoop.h"
#include "Socket.h"
#include "IOCPOperation.h"
#include "Log.h"

namespace dsth {

Connection::Connection(EventLoop* loop, int id, int socket_fd,
    const InetSocketAddress& host_addr, const InetSocketAddress& peer_addr) 
    : loop_(loop),
    socket_(new Socket(socket_fd)),
    read_op_(new IOCPWaiteOperation(socket_fd, std::make_pair(this, &Connection::OnReadSome))),
    write_op_(new IOCPWaiteOperation(socket_fd, std::make_pair(this, &Connection::OnWriteSome))),
    id_(id),
    host_addr_(host_addr), 
    peer_addr_(peer_addr) {
}


Connection::~Connection() {
    LOG_DEBUG("[Connection::~Connection] id:%d", id_);
}

void Connection::OnReadSome(int ec, DWORD bytes_transferred) {
    if (!ec) {
        message_handler_(this, &inbuffer_, Timestamp::GetNowTime());
    }
    else {
        printf("FixMe! OnReadSome error %d\n", ec);
    }
}

void Connection::OnWriteSome(int ec, DWORD bytes_transferred) {
    if (!ec) {
        write_completed_handler_(this);
    }
    else {
        printf("FixMe! OnWriteSome error %d\n", ec);
    }
    read_op_->Reset();
    loop_->AsyncRead(&inbuffer_, read_op_.get());
}

void Connection::Send(const char* data, size_t len) {
    write_op_->Reset();
    loop_->AsyncWrite(data, len, write_op_.get());
}

void Connection::Send(const std::string& data) {
    Send(data.c_str(), data.size());
}

void Connection::Send(const ChannelBuffer& buf) {
    Send(buf.Peek(), buf.ReadableBytes());
}

void Connection::ShutDown() {

}

void Connection::OnReadEnable(Timestamp recv_time) {}
void Connection::OnWriteEnable() {}
void Connection::OnErrorOccur() {}
void Connection::OnClose() {}
void Connection::HandleSocketError() {}
void Connection::ConnectEstablished() {
    conn_handler_(this);
    loop_->AsyncRead(&inbuffer_, read_op_.get());
}
void Connection::ConnectDestroy() {}

} // namespace
